﻿using SelfMadeMillionaire.Core.Entities;
using SelfMadeMillionaire.Core.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SelfMadeMillionaire.Core.Specifications.Newss
{
	public class NewsListSpecification : ISearchSpecification<News>
	{
		private DateTime? _startDate;
		private DateTime? _endDate;
		private ProductType? _productType;
		private string _title;
        private SubscriptionType? _minAccessLevel;
        private SubscriptionType? _minAccessLevelAdmin;

        public NewsListSpecification(DateTime? startDate, DateTime? endDate, ProductType? product, string title, SubscriptionType? minAccessLevel, SubscriptionType? minAccessLevelAdmin)
		{
			_startDate = startDate;
			_endDate = endDate;
			_productType = product;
			_title = string.IsNullOrWhiteSpace(title) ? null : title;
            _minAccessLevel = minAccessLevel;
            _minAccessLevelAdmin = minAccessLevelAdmin;
		}
        
		public IEnumerable<News> SatisfiedBy(IQueryable<News> entities)
		{
			var endDate = _endDate.HasValue ? _endDate.Value.AddDays(1) : DateTime.Now;
			bool isTitleNullOrWhiteSpace = string.IsNullOrWhiteSpace(_title);
			byte productType = _productType.HasValue ? (byte)_productType.Value : (byte)0;
            int minAccessLevel = _minAccessLevel.HasValue ? (int)_minAccessLevel.Value : -1;
            int minAccessLevelAdmin = _minAccessLevelAdmin.HasValue ? (int)_minAccessLevelAdmin.Value : -1;

			return entities.Where(p => (p.Date >= (_startDate.HasValue ? _startDate : p.Date)) &&
									(p.Date < (_endDate.HasValue ? endDate : p.Date)) &&
									
                                    (
                                        (p.ProductType == (productType > 0 ? productType : p.ProductType)) ||
                                        (p.Products.Any(x => x.ProductType == (productType > 0 ? productType : x.ProductType)))
                                    ) &&

                                    (p.MinAccessLevel <= (minAccessLevel >= 0 ? minAccessLevel : p.MinAccessLevel)) &&
                                    (p.MinAccessLevel == (minAccessLevelAdmin >= 0 ? minAccessLevelAdmin : p.MinAccessLevel)) &&
                                    (isTitleNullOrWhiteSpace ? true : p.Title.ToLower().Contains(_title.ToLower())) &&
									p.Status == (byte)StatusType.Active 
                                    )
							.OrderByDescending(x => x.Date);
		}
	}
}
